home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / dos / readitem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-12  |  5.2 KB  |  198 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: readitem.c,v 1.3 1996/08/13 13:52:50 digulla Exp $
  4.     $Log: readitem.c,v $
  5.     Revision 1.3  1996/08/13 13:52:50  digulla
  6.     Replaced <dos/dosextens.h> by "dos_intern.h" or added "dos_intern.h"
  7.     Replaced __AROS_LA by __AROS_LHA
  8.  
  9.     Revision 1.2  1996/08/01 17:40:56  digulla
  10.     Added standard header for all files
  11.  
  12.     Desc:
  13.     Lang: english
  14. */
  15. #include <clib/exec_protos.h>
  16. #include <dos/rdargs.h>
  17. #include <dos/dosasl.h>
  18. #include <dos/dosextens.h>
  19. #include "dos_intern.h"
  20.  
  21. /*****************************************************************************
  22.  
  23.     NAME */
  24.     #include <clib/dos_protos.h>
  25.  
  26.     __AROS_LH3(LONG, ReadItem,
  27.  
  28. /*  SYNOPSIS */
  29.     __AROS_LHA(STRPTR,           buffer,   D1),
  30.     __AROS_LHA(LONG,             maxchars, D2),
  31.     __AROS_LHA(struct CSource *, input,    D3),
  32.  
  33. /*  LOCATION */
  34.     struct DosLibrary *, DOSBase, 135, Dos)
  35.  
  36. /*  FUNCTION
  37.     Read an item from a given character source. Items are words
  38.     or quoted strings seperated by whitespace or '=' just like on
  39.     the commandline. The seperator is unread and the read string
  40.     is terminated by a NUL character.
  41.  
  42.     INPUTS
  43.     buffer   - Buffer to be filled.
  44.     maxchars - Size of the buffer. Must be at least 1 (for the terminator).
  45.     input    - A ready to use CSource structure or NULL which means
  46.            "read from the input stream".
  47.  
  48.     RESULT
  49.     One of ITEM_UNQUOTED - Normal word read.
  50.            ITEM_QUOTED   - Quoted string read.
  51.            ITEM_NOTHING  - End of line found. Nothing read.
  52.            ITEM_EQUAL    - '=' read. Buffer is empty.
  53.            ITEM_ERROR    - An error happened. IoErr() gives additional
  54.                            information in that case.
  55.  
  56.     NOTES
  57.     This function handles conversion of '**', '*"', etc inside quotes.
  58.  
  59.     EXAMPLE
  60.  
  61.     BUGS
  62.  
  63.     SEE ALSO
  64.  
  65.     INTERNALS
  66.  
  67.     HISTORY
  68.     29-10-95    digulla automatically created from
  69.                 dos_lib.fd and clib/dos_protos.h
  70.  
  71. *****************************************************************************/
  72. {
  73.     __AROS_FUNC_INIT
  74.     __AROS_BASE_EXT_DECL(struct DosLibrary *,DOSBase)
  75.  
  76. /* Macro to get a character from the input source */
  77. #define GET(c)                     \
  78. if(input!=NULL)                    \
  79. {                        \
  80.     if(input->CS_CurChr>=input->CS_Length)    \
  81.         c=EOF;                    \
  82.     else                    \
  83.         c=input->CS_Buffer[input->CS_CurChr++];    \
  84. }else                        \
  85. {                           \
  86.     c=FGetC(Input());                \
  87.     if(c==EOF&&*result)                \
  88.         return ITEM_ERROR;            \
  89. }
  90.  
  91. /* Macro to push the character back */
  92. #define UNGET() if(input!=NULL) input->CS_CurChr--; else UnGetC(Input(),-1);
  93.  
  94.     STRPTR b=buffer;
  95.     LONG c;
  96.     LONG *result=&((struct Process *)FindTask(NULL))->pr_Result2;
  97.     
  98.     /* Skip leading whitespace characters */
  99.     do
  100.     {
  101.         GET(c);
  102.     }while(c==' '||c=='\t'||c=='\n');
  103.  
  104.     if(!c||c=='\n'||c==EOF)
  105.     {
  106.         /*
  107.             End of line found. Note that unlike the Amiga DOS original
  108.             this funtion doesn't know about ';' comments. Comments are
  109.             the shell's job, IMO. I don't need them here.
  110.         */
  111.         if(c!=EOF)
  112.             UNGET();
  113.         *b=0;
  114.         return ITEM_NOTHING;
  115.     }else if(c=='=')
  116.     {
  117.         /* Found '='. Return it. */
  118.         *b=0;
  119.         return ITEM_EQUAL;
  120.     }else if(c=='\"')
  121.         /* Quoted item found. Convert Contents. */
  122.         for(;;)
  123.         {
  124.             if(!maxchars)
  125.             {
  126.                 *buffer=0;
  127.                 *result=ERROR_BUFFER_OVERFLOW;
  128.                 return ITEM_ERROR;
  129.             }
  130.             maxchars--;
  131.             GET(c);
  132.             /* Convert ** to *, *" to ", *n to \n and *e to 0x1b. */
  133.             if(c=='*')
  134.             {
  135.                 GET(c);
  136.                 /* Check for premature end of line. */
  137.                 if(!c||c=='\n'||c==EOF)
  138.                 {
  139.                     if(c!=EOF)
  140.                         UNGET();
  141.                     *buffer=0;
  142.                     *result=ERROR_UNMATCHED_QUOTES;
  143.                     return ITEM_ERROR;
  144.                 }else if(c=='n'||c=='N')
  145.                     c='\n';
  146.                 else if(c=='e'||c=='E')
  147.                     c=0x1b;
  148.             }else if(!c||c=='\n'||c==EOF)
  149.             {
  150.                 if(c!=EOF)
  151.                     UNGET();
  152.                 *buffer=0;
  153.                 *result=ERROR_UNMATCHED_QUOTES;
  154.                 return ITEM_ERROR;
  155.             }else if(c=='\"')
  156.             {
  157.                 /* " ends the item. */
  158.                 *b=0;
  159.                 return ITEM_QUOTED;
  160.             }
  161.             *b++=c;
  162.         }
  163.     else
  164.     {
  165.         /* Unquoted item. Store first character. */
  166.         if(!maxchars)
  167.         {
  168.             *buffer=0;
  169.             *result=ERROR_BUFFER_OVERFLOW;
  170.             return ITEM_ERROR;
  171.         }
  172.         maxchars--;
  173.         *b++=c;
  174.         /* Read upto the next terminator. */
  175.         for(;;)
  176.         {
  177.             if(!maxchars)
  178.             {
  179.                 *buffer=0;
  180.                 *result=ERROR_BUFFER_OVERFLOW;
  181.                 return ITEM_ERROR;
  182.             }
  183.             maxchars--;
  184.             GET(c);
  185.             /* Check for terminator */
  186.             if(!c||c==' '||c=='\t'||c=='\n'||c=='='||c==EOF)
  187.             {
  188.                 if(c!=EOF)
  189.                     UNGET();
  190.                 *b=0;
  191.                 return ITEM_UNQUOTED;
  192.             }
  193.             *b++=c;
  194.         }
  195.     }
  196.     __AROS_FUNC_EXIT
  197. } /* ReadItem */
  198.